package com.jiazhong.example.project.bookstore.front.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiazhong.example.project.bookstore.commons.bean.User;
import com.jiazhong.example.project.bookstore.commons.config.JwtConfig;
import com.jiazhong.example.project.bookstore.commons.handler.NotLoginException;
import com.jiazhong.example.project.bookstore.commons.handler.PasswordFailException;
import com.jiazhong.example.project.bookstore.commons.handler.UserNotFoundException;
import com.jiazhong.example.project.bookstore.commons.handler.UsernameNotFoundException;
import com.jiazhong.example.project.bookstore.commons.mapper.UserMapper;
import com.jiazhong.example.project.bookstore.commons.util.JsonResult;
import com.jiazhong.example.project.bookstore.commons.util.MD5Util;
import com.jiazhong.example.project.bookstore.commons.util.ResultTool;
import com.jiazhong.example.project.bookstore.front.service.UserService;
import io.jsonwebtoken.Claims;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    // 前台登陆redis的key前缀
    public static final String LOGIN_PREFIX = "user_front_";

    @Override
    public JsonResult login(User user) {
        log.info("用户开始登陆操作");
        User login = loadUsername(user.getUsername());
        if (login == null) {
            throw new UsernameNotFoundException("账号没有找到");
        }
        if (!Objects.equals(MD5Util.encryptMD5(user.getPassword()), login.getPassword())) {
            throw new PasswordFailException("密码错误");
        }
        // 如果该用户已经登陆，则提示不能登陆
        ValueOperations<String, String> forValue = stringRedisTemplate.opsForValue();
        String s = forValue.get(LOGIN_PREFIX + login.getId());
        if (s != null) {
            throw new UsernameNotFoundException("该账号已经登陆");
        }
        String token = JwtConfig.getJwtToken(login);
        forValue.set(LOGIN_PREFIX + login.getId(), token, 1, TimeUnit.DAYS);
        return ResultTool.success(token);
    }

    @Override
    public JsonResult isLogin(String token) {
        boolean b = JwtConfig.checkToken(token);
        if (!b) {
            throw new NotLoginException("用户没有登陆");
        }
        Claims claims = JwtConfig.parseJWT(token);
        Object userId = claims.get("id");
        ValueOperations<String, String> forValue = stringRedisTemplate.opsForValue();
        String redisToken = forValue.get(LOGIN_PREFIX + userId);
        if (!Objects.equals(redisToken, token)) {
            throw new NotLoginException("用户没有登陆");
        }
        return ResultTool.success(claims.get("name"));
    }

    @Override
    public JsonResult logout(String token) {
        boolean b = JwtConfig.checkToken(token);
        if (!b) {
            throw new NotLoginException("用户没有登陆");
        }
        Claims claims = JwtConfig.parseJWT(token);
        Object userId = claims.get("id");
        ValueOperations<String, String> forValue = stringRedisTemplate.opsForValue();
        String redisToken = forValue.get(LOGIN_PREFIX + userId);
        if (!Objects.equals(redisToken, token)) {
            throw new NotLoginException("用户没有登陆");
        }
        stringRedisTemplate.delete(LOGIN_PREFIX + userId);
        return ResultTool.success("success");
    }

    private User loadUsername(String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        queryWrapper.eq("status", 1);
        return getOne(queryWrapper);
    }
}
